﻿using System;
using System.Collections;
using System.Data;
using System.Reflection;
using System.Text;
using VitCode.ObjectResolutionHelper;

namespace VitCode.ObjectSettingApp
{
    /// <summary>
    /// 自动生成面页解析配置文件的附助类
    /// </summary>
    public class BaseDataSettingHelper : BaseHelper
    {
        /// <summary>
        /// 构建函数
        /// </summary>
        /// <param name="assName">应用程序集名称</param>
        public BaseDataSettingHelper(string assName)
        {
            SelObjTypes = new ArrayList();
            m_AssName = assName;
            InitInfo();
        }

        /// <summary>
        /// 应用程序集中的所有对象类型集合
        /// </summary>
        public ArrayList AssTypes { get; set; }

        /// <summary>
        /// 程序集选择需要处理对象类型集合
        /// </summary>
        public ArrayList SelObjTypes { get; set; }

        /// <summary>
        /// 获取自动生成指定对象类型的配置信息
        /// </summary>
        /// <param name="objType">指定的对象类型</param>
        /// <returns>配置信息</returns>
        public string GetClassContext(Type objType)
        {
            return GetClassContext(objType, m_AssName);
        }


        /// <summary>
        /// 获取自动生成指定对象类型的配置信息
        /// </summary>
        /// <param name="objType">指定的对象类型</param>
        /// <param name="assName">指定的应用程序集名称</param>
        /// <returns>配置信息</returns>
        public string GetClassContext(Type objType, string assName)
        {
            m_Checker.CheckClass(objType);
            string strDes = LookUpClassHelper.GetOrMemoDesValue(objType);
            PropertyInfo[] pros = LookUpClassHelper.GetPros(objType);
            var sb = new StringBuilder();
            PropertyInfo pId = objType.GetProperty("Id");
            if (pId == null)
                throw new Exception("对象解析框架要求对象必需包含Id属性");
            sb.Append("\t<" + objType.Name + " KeyProperty=\"Id\" AssemblyName=\"" + m_AssName + "\" NameSpace=\"" +
                      objType.Namespace + "\" Memo=\"" + strDes + "\">\r\n");

            foreach (PropertyInfo p in pros)
            {
                var strProDes = LookUpClassHelper.GetOrMemoDesValue(p);
                if (!p.CanWrite || string.IsNullOrEmpty(strProDes) || p.Name == HistoryKeyInfo.CURR_HIS_ID)
                    continue;
                string strNode = GetProContext(p);
                if (!string.IsNullOrEmpty(strNode))
                    sb.Append(strNode + "\r\n");
            }

            sb.Append(GetSqlListNodeXml(objType,false));
            sb.Append("\t</" + objType.Name + ">");
            return sb.ToString();
        }

        /// <summary>
        /// 获取自动生成的属性配置信息
        /// </summary>
        /// <param name="pro">属性</param>
        /// <returns>配置信息</returns>
        private string GetProContext(PropertyInfo pro)
        {
            if (pro == null)
                return "";
            if (pro.Name == "Id")
                return "";
            string dbTypeName = m_DbTypeMapping.Get(pro.PropertyType.ToString());//检验属性的类型是不是基础数据类型,返回它在DB上对象的类型名称,如果没有,那就说明是,子对象属性
            string strDes = LookUpClassHelper.GetOrMemoDesValue(pro);
            string val = "";

            if (string.IsNullOrEmpty(dbTypeName))//为空字符串,就是子对象类型,需要为此属性绑定子对象选择控件
            {
                if (!AssTypes.Contains(pro.PropertyType))
                {
                    if (!SelObjTypes.Contains(pro.PropertyType))
                        SelObjTypes.Add(pro.PropertyType);
                }
                val = "\t\t<property Name=\"" + pro.Name + "\"  ClassName=\"" + pro.PropertyType.Name + "\" Memo=\"" +
                      strDes + "\" UserCtlPath=\"../UserControls/ChildObjectSetCtl.ascx\"" +
                      " CtlProInfo=\"ObjClassName:" + pro.PropertyType.Name +
                      ",ObjKeyProName:Id,ObjShowProName:Name\" CtlObjKeyPro=\"ObjKeyProVal\" CtlObjShowPro=\"ObjShowProVal\" ></property>";
            }
            else if (pro.PropertyType == typeof (DateTime))//对于日期类型需要绑定日期用户控件
            {
                val =
                    "\t\t<property Name=\"" + pro.Name + "\" Memo=\"" + strDes +
                    "\" UserCtlPath=\"../UserControls/DateCtl.ascx\"  FormatString=\"yyyy-MM-dd\"></property>";
            }
            else//以下的就是对基础数据类型的处理
            {
                var sb = new StringBuilder();
                var maxLen = GetProMaxLength(pro);
                if (maxLen == 0) maxLen = 50;
                if (maxLen > 50)
                {
                    sb.Append(
                        "\t\t<property Name=\"" + pro.Name +
                        "\" CtlProInfo=\"TextMode:MultiLine,Rows:5,Width:360px\" Memo=\"" + strDes + "\" >");
                    sb.Append("\r\n\t\t\t<page_rule TypeName=\"长度限制_" + maxLen + "\"></page_rule>\r\n\t\t");
                }
                else
                    sb.Append("\t\t<property Name=\"" + pro.Name + "\" Memo=\"" + strDes + "\" CtlProInfo=\"MaxLength:" +
                              maxLen + "\">");
                if (m_UniquePros.Contains(pro.Name))//判断是否对此属性进行唯一约束
                    sb.Append(
                        "\r\n\t\t\t<page_rule TypeName=\"必填\"></page_rule>\r\n\t\t\t<db_rule TypeName=\"唯一性\"></db_rule>\r\n\t\t");
                sb.Append("</property>");
                sb.Append("\r\n\t\t<property></property>");
                val = sb.ToString();
            }
            return val;
        }
    }
}